import {
  Body,
  Controller,
  Del,
  Get,
  Inject,
  Param,
  Post,
  Put,
} from '@midwayjs/core';
import { Area, AreaInsertDto, AreaQC } from '../entity/area.entity';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import { address } from '../entity/address.entity';
import { BillCodeGenerator } from '../service/IdTool.entity';
import { MissTargetError } from '../filter/Error.filter';
@Controller('/Area')
export class AreaController {
  @Get('/showtime')
  async showtime() {
    return 'hello midway';
  }
  @InjectEntityModel(Area)
  repoAr: Repository<Area>;
  @InjectEntityModel(address)
  repoAd: Repository<address>;
  @Post('/query')
  async query(@Body() dto: AreaQC) {
    const {
      areaNameLike,
      addressNameLike,
      cityNameLike,
      pageSize,
      pageNum,
      minTime,
      maxTime,
    } = dto;
    const pageStart = (pageNum - 1) * pageSize;
    const build1 = this.repoAr.createQueryBuilder('ar');
    build1.leftJoin(address, 'ad', 'ar.areaCode=ad.addressFk');
    if (areaNameLike) {
      build1.andWhere('ar.areaName like :arn ', {
        arn: '%' + areaNameLike + '%',
      });
    }
    if (addressNameLike) {
      build1.andWhere('ad.addressName like :adn ', {
        adn: '%' + addressNameLike + '%',
      });
    }
    if (cityNameLike) {
      build1.andWhere('ad.cityName like :cn ', {
        cn: '%' + cityNameLike + '%',
      });
    }
    if (maxTime) {
      build1.andWhere('ar.createTime < :ma', { ma: maxTime });
    }
    if (minTime) {
      build1.andWhere('ar.createTime > :mi', { mi: minTime });
    }
    build1.groupBy('ar.areaCode');
    build1.orderBy('createTime', 'ASC');
    console.log(pageNum);
    console.log(pageSize);
    console.log(pageStart);
    build1.offset(pageStart).limit(pageSize);
    const r1 = await build1.printSql().getManyAndCount();
    const ids = r1[0].map(ar => ar.areaCode);
    console.log(ids);
    if (ids.length === 0) {
      return {
        results: [],
        total: 0,
      };
    }
    const build2 = this.repoAr.createQueryBuilder('ar');
    build2.leftJoinAndMapMany(
      'ar.address',
      address,
      'ad',
      'ar.areaCode=ad.addressFk'
    );
    build2.where('ar.areaCode in (:...ids)', { ids: ids });
    build2.orderBy('ar.areaCode', 'DESC');
    const r2 = await build2.printSql().getManyAndCount();
    return {
      results: r2[0],
      total: r1[1],
    };
  }
  @Inject()
  billCodeInfo: BillCodeGenerator;
  @Post('/insert')
  async insert(@Body() dto: AreaInsertDto) {
    const ar = new Area();
    ar.areaCode = await this.billCodeInfo.nextCode('Ar');
    ar.address = dto.address;
    ar.areaName = dto.areaName;
    ar.createTime = new Date();
    dto.address.forEach((address: address, index: number) => {
      address.addressFk = ar.areaCode;
      address.addressCode = index.toString();
    });
    ar.address = dto.address;
    await this.repoAr.save(ar);
    await this.repoAd.save(ar.address);
    return ar;
  }
  @Get('/find/:code')
  async find(@Param('code') code: string) {
    const build = await this.repoAr.createQueryBuilder('ar');
    build.leftJoinAndMapMany(
      'ar.address',
      address,
      'ad',
      'ar.areaCode=ad.addressFk'
    );
    const r = build.where('ar.areaCode = :c', { c: code }).getOne();
    if (!r) {
      throw new MissTargetError('待查看数据不存在');
    }
    return r;
  }
  @Put('/modify/:code')
  async modify(@Param('code') code: string, @Body() dto: AreaInsertDto) {
    const ar = await this.repoAr.findOneBy({ areaCode: code });
    if (!ar) {
      throw new MissTargetError('待修改的单据不存在');
    }
    ar.areaName = dto.areaName;
    ar.createTime = new Date(ar.createTime);
    dto.address.forEach((address: address, index: number) => {
      address.addressFk = ar.areaCode;
      address.addressCode = index.toString();
    });
    ar.address = dto.address;
    await this.repoAr.save(ar);
    await this.repoAd.delete({ addressFk: ar.areaCode });
    await this.repoAd.save(ar.address);
    return ar;
  }
  @Del('/remove/:code')
  async remove(@Param('code') code: string) {
    const ar = await this.repoAr.findOneBy({ areaCode: code });
    if (!ar) {
      throw new MissTargetError('待删除的单据不存在');
    }
    await this.repoAd.delete({ addressFk: ar.areaCode });
    return this.repoAr.remove(ar);
  }
}
// {
//   "address": [
//     {
//       "addressCode": "3",
//       "addressName": "淄博-张店",
//       "cityName": "淄博",
//       "addressFk": "1"
//     },
//     {
//       "addressCode": "2",
//       "addressName": "潍坊-安丘",
//       "cityName": "潍坊",
//       "addressFk": "1"
//     },
//     {
//       "addressCode": "1",
//       "addressName": "潍坊-寿光",
//       "cityName": "潍坊",
//       "addressFk": "1"
//     }
//   ],
//   "areaCode": "1",
//   "areaName": "华东",
//   "createTime": "2023-06-30T16:00:00.000Z"
// }
